import hashlib
import struct
import socket

from chat.client import client_database
from chat.common.RSA_file import USR
import chat.client.gol


def get_socket():
    """客户端监听socket传入的函数"""
    ip = '::1'
    port = 2333
    server_address = (ip, port)
    s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)  # 创建套接字
    s.connect(server_address)  # 连接服务器
    chat.client.gol.set_value("socket_obj",s)
    return s


def get_recv_code(s):
    """
    处理返回值
    :param s: socket对象
    :return: 处理结果
    """
    data_len = int.from_bytes(s.recv(4), 'little')
    data_type = int.from_bytes(s.recv(4), 'little')
    data = s.recv(data_len)
    if data_type == 0:  # 注册
        data = int.from_bytes(data, 'little')
        s.close()
        if data > 0x00ff:  # 注册成功
            print("register success")
            return data
        elif data == 0x1:  # 用户名已经注册
            print("username repeat")
            return 1
        elif data == 0x2:  # 邮箱已注册
            print("email repeat")
            return 2
        elif data == 0x3:  # 邮箱验证码错误
            print("email code err")
            return 3
        else:
            print("[data] >> ", data)
            return False
    elif data_type == 1:  # 账号登录
        data = int.from_bytes(data, 'little')
        if data == 0:  # 注册成功
            print("login success")
            chat.client.gol.set_value("login_flag", "username")
            username = chat.client.gol.get_value("socket_username")
            client_database.encrypt_room_private_key(username, "username")
            return 0
        elif data == 0x1:  # err
            print("login err")
            return 1
    elif data_type == 2:  # 邮箱登录
        ans = data[:2]
        ans = int.from_bytes(ans, 'little')
        if ans == 0:  # 登录成功
            print("login success")
            username_len = int.from_bytes(data[2:4], 'little')
            username = str.encode(data[4:4+username_len])
            chat.client.gol.set_value("socket_username", username)
            email = chat.client.gol.get_value("socket_email")
            client_database.decrypt_private_key_byemail(username, email)
            chat.client.gol.set_value("login_flag", "email")
            client_database.encrypt_room_private_key(username, "email")
            return 0
        elif ans == 0x1:  # err
            print("login err")
            return 1
    elif data_type == 3:  # 邮箱验证
        data = int.from_bytes(data, 'little')
        s.close()
        if data == 0:  # 验证码发送成功
            print("send e-mail code success")
            return 0
        elif data == 0x1:  # err
            print("send e-mail code err")
            return 1
    else:  # debug
        print("[data_type] >> ", data_type)
        return False


def socket_register(username, email, passwd, code):
    """
    注册socket连接
    :param username: 用户名
    :param email: 邮箱
    :param passwd: 密码
    :param code: 验证码
    :return:
    """
    usr_key = USR()
    pubkey = usr_key.pubkey
    pubkey_n = usr_key.n
    pubkey = str(pubkey)
    pubkey_n = str(pubkey_n)
    plain_passwd = passwd
    passwd = hashlib.sha256(plain_passwd.encode()).hexdigest()

    server = get_socket()
    head2 = struct.pack("<HHHHII", len(username), len(email), len(passwd), len(code), len(pubkey), len(pubkey_n))
    data = head2 + str.encode(username) + str.encode(email) + str.encode(passwd) + str.encode(code) + str.encode(
        pubkey) + str.encode(pubkey_n)
    head = struct.pack("<i", len(data)) + b'\x00\x00\x00\x00'
    msg = head + data
    server.send(msg)
    res = get_recv_code(server)
    if res > 0x1100:
        print(">>", res)
        user_id = res - 0x1100
        user_id = int(chr(user_id))
        # 注册成功 本地需新建数据库存入信息与私钥usr_key.privkey与usr_key.n并加密数据库
        client_database.create_username_database(user_id, username, passwd, email, usr_key.privkey, usr_key.n, plain_passwd)
        return 0

    return res


def socket_login_username(username, passwd):
    # chat.client.gol.init()
    chat.client.gol.set_value("socket_username", username)
    chat.client.gol.set_value("plain_passwd", passwd)
    # print("s>", chat.client.gol.get_value("socket_username"))
    plain_passwd = passwd
    passwd = hashlib.sha256(passwd.encode('utf-8')).hexdigest()
    server = get_socket()
    head2 = struct.pack("<HH", len(username), len(passwd))
    data = head2 + str.encode(username) + str.encode(passwd)
    head = struct.pack("<i", len(data)) + b'\x01\x00\x00\x00'
    msg = head + data
    print(msg)
    server.send(msg)
    res = get_recv_code(server)
    server_socket = server
    if res == 0:        # 登陆成功 解密数据库密钥
        client_database.decrypt_private_key_bypwd(username, plain_passwd)
        # pass

    return res


def socket_login_email(email, code):
    # chat.client.gol.init()
    server = get_socket()
    head2 = struct.pack("<HH", len(email), len(code))
    data = head2 + str.encode(email) + str.encode(code)
    head = struct.pack("<i", len(data)) + b'\x02\x00\x00\x00'
    msg = head + data
    server.send(msg)
    res = get_recv_code(server)
    chat.client.gol.set_value("socket_email", email)
    server_socket = server
    return res


def socket_check_email(email):
    server = get_socket()
    data = str.encode(email)
    head = struct.pack("<i", len(data)) + b'\x03\x00\x00\x00'
    msg = head + data
    print(msg)
    server.send(msg)
    server.close()

# socket_check_email("2578653827@qq.com")
# socket_register("mark", "2578653827@qq.com", "password1", "0000")
# socket_login_username("mark", "password1")
# socket_login_email("2578653827@qq.com", "0000")
